/*
 *   Copyright 2012, Thomas Kerber
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package milk.jpatch.attribs;

import java.util.List;

import milk.jpatch.CPoolMap;
import milk.jpatch.Patch;

import org.apache.bcel.classfile.Attribute;

// TODO: BootstrapMethods
/**
 * Denotes the patch of a java "Attribute".
 * @author Thomas Kerber
 * @version 1.0.2
 */
public abstract class AttributePatch implements Patch<List<Attribute>>{
    
    private static final long serialVersionUID = -4783803184999541927L;
    
    @Override
    public abstract List<Attribute> patch(
            List<Attribute> attribs,
            CPoolMap map);
    
    /**
     * Replaces all attributes of a certain type.
     * @param attributes The list of attributes within which to replace.
     * @param typeName The type of attribute to replace. (Official JVM name)
     * @param replaceWith The attribute to replace it with. If this is null,
     *         all attributes of the type will be removed instead of replaced.
     * @return The list with replacements.
     */
    protected static List<Attribute> replaceTypeWith(
            List<Attribute> attributes,
            String typeName,
            Attribute replaceWith){
        int pos = findName(attributes, typeName);
        if(pos == -1){
            if(replaceWith != null)
                attributes.add(replaceWith);
        }
        else if(replaceWith != null)
            attributes.set(pos, replaceWith);
        else
            attributes.remove(pos);
        return attributes;
    }
    
    /**
     * Finds the first attribute of a certain type.
     * @param attributes The attributes list to search.
     * @param name The attribute type to search for.
     * @return The first attributes index, or -1 if none is found.
     */
    protected static int findName(
            List<Attribute> attributes,
            String name){
        for(int i = 0; i < attributes.size(); i++){
            if(attributes.get(i).getName().equals(name))
                return i;
        }
        return -1; // Not found
    }
    
}
